<template>
  <el-row
    type="flex"
    ref="faultTree"
    justify="center"
    style="flex-direction: column; height: 100%;"
  >
    <el-col
      :span="24"
      :class="`player-${layoutType}`"
      element-loading-background="rgba(0, 0, 0, 0.7)"
      element-loading-spinner="el-icon-loading"
      element-loading-text="正在同步视频缓存..."
    >
      <el-col
        :class="['video-control', `video-control-${layout}`]"
        v-for="index in 16"
        :key="index"
      >
        <span v-if="index <= layout">
          <div
            style="height: 100%;"
            v-if="index === 1"
            @dblclick="fullScreen"
          >
            <VideoBox
              ref="videoBox"
              :draggable="true"
              :playback-rate="playbackRate"
              :preload="preload"
              :show-screenshot="showScreenshot"
              :now-time="currentTime"
              :play="playVideo"
              :video-info="list[sort[index-1]]"
              :muted="false"
              :volume-value="volumeValue"
              @pause="pauseHandle"
              @play="playHandle"
              @canplay-vedio="canplay"
              @ended="ended"
              @timeupdate="timeupdate"
              @changeStatus="changeStatus"
            />
          </div>
          <div
            style="height: 100%;"
            v-else
            @dblclick="changeMain(index-1)"
          >
            <VideoBox
              ref="videoBox"
              :draggable="true"
              :playback-rate="playbackRate"
              :preload="preload"
              :show-screenshot="showScreenshot"
              :now-time="currentTime"
              :play="playVideo"
              :video-info="list[sort[index-1]]"
              :muted="true"
              :volume-value="0"
              :default-muted="true"
              @changeStatus="changeStatus"
            />
          </div>
        </span>
      </el-col>
    </el-col>
    <el-col
      :span="24"
      class="controls"
    >
      <span class="btn">
        <i
          type="primary"
          class="el-icon-headset"
        >
          音量
        </i>
        <el-slider
          style="padding-left: 10px;padding-right: 10px;"
          @change="changeVolume"
          class="slider"
          v-model="volumeValue"
        />
      </span>
      <span style="margin-right: 7px;">
        <el-button
          @click="changePlaybackRateIndex(-1)"
          type="primary"
          icon="el-icon-d-arrow-left"
          size="mini"
          circle
        />
        <el-button
          v-if="!play"
          @click="changePlay"
          type="primary"
          icon="el-icon-caret-right"
          size="small"
          circle
        />
        <el-button
          v-else
          @click="changePlay"
          type="danger"
          icon="el-icon-switch-button"
          size="small"
          circle
        />
        <el-button
          @click="changePlaybackRateIndex(1)"
          type="primary"
          icon="el-icon-d-arrow-right"
          size="mini"
          circle
        />
      </span>
      <span
        class="playback-rate"
        @click="initPlaybackRateIndex"
      > {{ playbackRate.toFixed(1) }}x </span>
      <span
        v-for="(val, key) in layouts"
        :key="key"
        @click="changeLayout(key)"
        class="theme"
      >
        <i :class="['el-icon-menu', key === layoutIndex ? 'active' : '']">
          {{ val }}
        </i>
      </span>
      <span style="margin: 0 5px; ">
        <slot name="buttons" />
      </span>
      <!-- <span style="margin: 0 5px;">
        <el-checkbox v-model="asyncPlay">同步播放</el-checkbox>
      </span>
      <span style="margin: 0 5px;">
        <el-checkbox v-model="preload">预加载</el-checkbox>
      </span> -->
    </el-col>
    <el-col
      :span="24"
      class="controls"
    >
      <span style="display:flex; align-items: center">
        <!-- <span>{{ formatTime(startTime) }}/{{ formatTime(endTime) }}</span> -->
        <el-slider
          style="width:80%; padding-left: 30px;"
          :min="0"
          :max="duration"
          :step="1000"
          :format-tooltip="setProcessToolTip"
          v-model="progressValue"
          @input="inputProgress"
        />
      </span>
    </el-col>
  </el-row>
</template>

<script>
// import { Component, Vue, Watch, Prop, Emit } from 'vue-property-decorator'
import VideoBox from './VideoBox.vue'
import html2canvas from 'html2canvas'
export default {
  components: {
    VideoBox
    // VideoPlayer,
    // Comment
  },
  data(){
    return{
      layoutIndex: 2,// 当前布局种类
      layouts: [2, 3, 4, 8, 16], // 布局种类
      sort: [],
      seekedTime: 0,
      playbackRateIndex: 4,
      playbackRateOptions: [0.1, 0.2, 0.5, 0.8, 1.0, 1.2, 1.5, 2.0, 3.0, 5.0, 8.0, 10, 12], // 播放速率选择列表
      asyncLoading: false,
      showScreenshot: false,
      asyncPlay: true,
      preload: true,
      progressValue: 0,
    }
  },
  props:{
    list: {
      type: Array,
      default() {
        return []
      }
    },
    layout: {
      type: Number,
      default: 0
    },
    volume: {
      type: Number,
      default: 0
    },
    currentTime: {
      type: Number,
      default: 0
    },
    play:{
      type: Boolean,
      default: false
    },
    progress: {
      type: Number,
      default: 0
    },
    // startTime: {
    //   type: Number,
    //   default: 0
    // },
    // endTime: {
    //   type: [Number, String],
    //   default: 0
    // },
    formatTime: {
      type: Function,
      default(val) {
        return val
      }
    },
    layoutType: {
        type: [Number, String],
        default: 0
    }
  },
  methods: {
    // 格式化开始播放时间
    currentStartTime() {
      return this.startTime + this.progress
    },
    // 视频总时长（毫秒）
    duration() {
      return this.endTime - this.startTime
    },
    // 主播放文件
    mainVideo() {
      return this.list[0]
    },
    // 子播放文件列表
    childVideos() {
      if (this.list && this.list.length > 0) {
        const items = [...this.list]
        const result = items.splice(1, items.length - 1)
        return result
      }
      return []
    },
    // 音量
    // volumeValue() {
    //   return this.volume
    // },
    // volumeValue(value) {
    //   this.$emit('update:volume', value)
    // },
    // // 是否正在同步视频
    // asyncing() {
    //   return this.asyncPlay ? this.asyncLoading : false
    // },
    // 是否播放视频
    playVideo() {
      return this.play && !(this.asyncPlay ? this.asyncLoading : false)
    },
    // 播放速率
    // playbackRate() {
    //   return this.playbackRateOptions[this.playbackRateIndex]
    // },
    layout() {
      return this.layouts[this.layoutIndex]
    },
    // 改变播放盒子数量
    changeLayout(index) {
      // 判断是否有新增的视频盒子，有则需要重新设置当前播放时间以达到同步播放
      if (index > this.layoutIndex && this.layoutIndex < this.list.length) {
        const seekedTime = this.seekedTime
        this.$nextTick(() => {
          this.changeCurrentTime(seekedTime)
        })
      }
      this.layoutIndex = index
    },
      // 改变主视频播放文件
    changeMain(index) {
      if (this.list[index]) {
        const seekedTime = this.seekedTime
        const newIndex = this.sort[index]
        const [oldIndex] = this.sort.splice(0, 1, newIndex)
        this.sort.splice(index, 1, oldIndex)
        // 添加到宏任务队列
        setTimeout(() => {
          this.changeCurrentTime(seekedTime)
        })
      }
    },
    changeCurrentTime(time) {
      return time
    },
    changePlay() {
      return !this.play
    },
    pauseHandle() {
      return false
    },
    playHandle() {
      return true
    },
    // 改变音量
    changeVolume(value) {
      this.$emit('update:volume', value)
      this.$emit('changeVolume', value)
    },
    changeProgress(value) {
      return value
    },
    canplay(duration) {
      return duration
    },
    ended() {
      return true
    },
    timeupdate(time) {
      this.seekedTime = time
      return time
    },
      // 获取屏幕快照
    getSnapshoot() {
      const isPlay = this.play
      // 由于canvas的限制，需要暂停视频转换为img图片，截图完成后恢复播放状态
      this.pauseHandle()
      const ref = (this.$refs.faultTree).$el
      const videoBoxs = this.$refs.videoBox
      if (videoBoxs && videoBoxs.length > 0) {
        // 先将每个视频子模块截图，然后再汇总截图
        const handles = videoBoxs.map((videoBox) => videoBox.getSnapshoot())
        Promise.all(handles)
        this.showScreenshot = true
        return new Promise((resolve, reject) => {
          this.$nextTick(async() => {
            const canvas = html2canvas(ref, {
              backgroundColor: null,
              allowTaint: true,
              useCORS: true
            })
            const dataURL = canvas.toDataURL('image/jpeg')
            this.showScreenshot = false
            this.$emit('update:play', isPlay)
            resolve(dataURL)
          })
        })
      } else {
        return Promise.resolve()
      }
    },
    changeStatus() {
      const videoBoxs = this.$refs.videoBox
      if (videoBoxs && videoBoxs.length > 0) {
        this.asyncLoading = videoBoxs.some((videoBox) => !!videoBox.loading)
      } else {
        this.asyncLoading = false
      }
    },
    changePlaybackRateIndex(value) {
      const result = this.playbackRateIndex + value
      if (result < 0 || result >= this.playbackRateOptions.length) return
      this.playbackRateIndex = result
    },
    initPlaybackRateIndex() {
      this.playbackRateIndex = 4
    },
    fullScreen() {
      const videoBoxs = this.$refs.videoBox
      if (videoBoxs && videoBoxs.length > 0) {
        videoBoxs[0].fullScreen()
      }
    },
    setProcessToolTip(value) {
      return this.formatTime(this.startTime + value)
    }
  },
  Watch:{
    onListChange(newVal, oldVal) {
      if (this.sort.length !== this.list.length) {
        this.sort.splice(0)
        for (let i = 0; i < this.list.length; i += 1) {
          this.sort.push(i)
        }
      }
      if (newVal.length === oldVal.length) return
      const index = this.layouts.findIndex(num => num >= this.list.length)
      if (index > -1) {
        this.layoutIndex = index
      } else {
        this.layoutIndex = (this.layouts.length - 1) / 2
      }
    },
    inputProgress(value, old) {
    // 若是progress监听的数据，则更新progressValue的值，否则是拖动出发的事件，需触发视频进度的更新
      if (!old && value !== this.progress) {
        this.changeProgress(value)
      } else {
        this.progressValue = value
      }
    },
    onAsyncPlayChange(value) {
      if (value) {
        this.changeCurrentTime(this.seekedTime)
      }
    }
  },
  mounted() {
    this.sort.splice(0)
    for (let i = 0; i < this.list.length; i += 1) {
      this.sort.push(i)
    }
  }
}
</script>

<style scoped>
  .player-0 {
    height: calc(100% - 40px);
    overflow: hidden;


  }
    .player-0  .video-control:first-child {
      padding: 1px;
      border: 2px solid #ccc;
    }
  .player-0  .video-control-2 {
      width: 50%;
      height: 100%;
    }
  .player-0  .video-control-2:first-child {
      width: 50%;
      height: 100%;
    }
  .player-0  .video-control-3 {
      width: 34%;
      height: 50%;
    }
  .player-0  .video-control-3:first-child {
      width: 66%;
      height: 100%;
    }
  .player-0  .video-control-4 {
      width: 34%;
      height: 33.33333%;
    }
  .player-0  .video-control-4:first-child {
      width: 66%;
      height: 100%;
    }
  .player-0  .video-control-8 {
      width: 25%;
      height: 25%;
    }
  .player-0  .video-control-8:first-child {
      width: 75%;
      height: 75%;
    }
  .player-0  .video-control-16 {
      width: 16.66667%;
      height: 25%;
    }
  .player-0  .video-control-16:first-child {
      width: 50%;
      height: 75%;
    }
  .player-0  .video-control {
      padding: 1px;
      border: 2px solid #ccc;
      box-sizing: border-box;
    }
  .player-1 {
    height: calc(100% - 40px);
    overflow: hidden;
  }
  .player-1    .video-control {
      padding: 1px;
      border: 2px solid #ccc;
      box-sizing: border-box;
    }
   .player-1 .video-control:first-child {
      padding: 1px;
      border: 2px solid #ccc;
    }
   .player-1 .video-control-2 {
      width: 100%;
      height: 50%;
    }
   .player-1 .video-control-2:first-child {
      width: 100%;
      height: 50%;
    }
   .player-1 .video-control-3 {
      width: 50%;
      height: 30%;
    }
  .player-1  .video-control-3:first-child {
      width: 100%;
      height: 70%;
    }
  .player-1  .video-control-4 {
      width: 33.33333%;
      height: 25%;
    }
   .player-1 .video-control-4:first-child {
      width: 100%;
      height: 75%;
    }
  .player-1  .video-control-8 {
      width: 25%;
      height: 25%;
    }
  .player-1  .video-control-8:first-child {
      width: 75%;
      height: 75%;
    }
  .player-1  .video-control-16 {
      width: 25%;
      height: 16.66667%;
    }
  .player-1  .video-control-16:first-child {
      width: 75%;
      height: 49.9%;
    }
  .controls {
    height: 40px;
    background: #d4dff3;
    font-size: 14px;
    line-height: 40px;
    padding: 2px;


  }
    .controls  .theme {
      padding: 2px 4px;
      margin-right: 4px;
      cursor: pointer;
      border-radius: 5px;
      border: 1px solid #c0c4cc;
      background-color: #ffffff;
    }
  .controls  .playback-rate {
      padding: 2px;
      margin-right: 7px;
      cursor: pointer;
      border-radius: 5px;
      font-size: 12px;
      color: rgb(255, 255, 255);
      font-weight: bold;
      background-color: rgb(0, 150, 136);
    }
  .controls  .slider {
      width: 100px;
      display: inline-block;
      vertical-align: middle;
    }
    .controls  .btn {
      padding: 2px 4px;
      margin-right: 4px;
      cursor: pointer;
      max-width: 100px;
      i {
        font-size: 13px;
      }
    }
  .el-icon-menu.active {
    color: #dd6161;
  }
</style>
